/*******************************************************************************
 * Copyright (c) 2006 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/
package com.cea.papyrus.core.commands.association;

import org.eclipse.core.runtime.Assert;
import org.eclipse.uml2.uml.Association;
import org.eclipse.uml2.uml.Classifier;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.Property;

import com.cea.papyrus.core.IPapyrusUIConstants;
import com.cea.papyrus.core.commands.PapyrusCommand;
import com.cea.papyrus.core.helper.IGraphEdgeHelper;
import com.cea.papyrus.core.helper.IModelerHelper;
import com.cea.papyrus.core.helper.ModelerHelper;
import com.cea.papyrus.core.utils.Debug;

/**
 * Command that deletes an association from the model.
 */
public class DeleteAssociationFromModelCommand extends PapyrusCommand {
	
	/**
	 * debug channel.
	 */
	private final static int channel = 21;
	
	/**
	 * Dependency to delete.
	 */
	private org.eclipse.uml2.uml.Association association;
	
	/**
	 * Owner of the dependency to delete.
	 */
	private Element parent;
	
	/**
	 * stores the source property.
	 */
	private Property sourceProperty;
	
	/**
	 * stores the source property owner.
	 */
	private Classifier sourcePropertyOwner;
	
	/**
	 * stores the target property.
	 */
	private Property targetProperty;
	
	/**
	 * stores the target property owner.
	 */
	private Classifier targetPropertyOwner;

	/**
	 * Creates a new DeleteAssociationFromModelCommand.
	 * 
	 * @param association the association to delete
	 */
	public DeleteAssociationFromModelCommand(Association association) {
		super(Association.class);
		Assert.isNotNull(association);
		setLabel("Delete Association "+association.getName());
		this.association = association;
		parent = association.getOwner();
		
		// save properties
		this.sourceProperty = (Property)association.getMemberEnds().get(1);
		this.sourcePropertyOwner = (Classifier)sourceProperty.getOwner();
		this.targetProperty = (Property)association.getMemberEnds().get(0);
		this.targetPropertyOwner = (Classifier)targetProperty.getOwner();
		
	}
    
	/* (non-Javadoc)
	 * @see org.eclipse.gef.commands.Command#execute()
	 */
	/**
	 * 
	 */
	@Override
	public void execute() {
		Debug.debug(this, "DeleteAssociationFromModel.execute -> "+association, channel);
		Assert.isNotNull(parent, "DeleteAssociation.child has no parent");
		
		// delete using connect/reconnect
		if(elementFactory instanceof IGraphEdgeHelper) {
			IModelerHelper classDiagramModelerHelper = ModelerHelper.getFactory(IPapyrusUIConstants.CLASS_DIAGRAM);
			
			// deconnect association from properties
			classDiagramModelerHelper.deconnect(Association.class, sourceProperty, targetProperty, association);
			
			// remove properties
			classDiagramModelerHelper.removeElement(Property.class, sourceProperty, sourcePropertyOwner);
			classDiagramModelerHelper.removeElement(Property.class, targetProperty, targetPropertyOwner);
			
			// remove association
			classDiagramModelerHelper.removeElement(Association.class, association, parent);
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.gef.commands.Command#redo()
	 */
	/**
	 * 
	 */
	@Override
	public void redo() {
		execute();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.gef.commands.Command#undo()
	 */
	/**
	 * 
	 */
	@Override
	public void undo() {
		Debug.debug(this, "DeleteAssociationFromModel.execute -> "+association, channel);
		Assert.isNotNull(parent, "DeleteAssociation.child has no parent");
		
		// undo delete using connect/reconnect
		if(elementFactory instanceof IGraphEdgeHelper) {
			IModelerHelper classDiagramModelerHelper = ModelerHelper.getFactory(IPapyrusUIConstants.CLASS_DIAGRAM);
			
			// recreate association
			classDiagramModelerHelper.addUMLElement(Association.class, association, parent);
			
			// recreate properties
			classDiagramModelerHelper.addUMLElement(Property.class, targetProperty, targetPropertyOwner);
			classDiagramModelerHelper.addUMLElement(Property.class, sourceProperty, sourcePropertyOwner);
			
			// connect association and properties
			classDiagramModelerHelper.connect(Association.class, sourceProperty, targetProperty, association);
			
		}

		
		
	}
}
